﻿using Abp.Collections.Extensions;
using Abp.Dependency;
using Abp.Extensions;
using Abp.Threading;
using Mt.Site.Core.Organizations.UserCache.Models;
using Mt.Site.Core.WorkFlows.Design;
using Mt.Site.Core.WorkFlows.Design.Cache;
using Mt.Site.Core.WorkFlows.Enum;
using Mt.Site.Core.WorkFlows.Process;
using Mt.Site.Core.WorkFlows.Process.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Mt.Site.Core.WorkFlows.Diy.Plugin
{
    public abstract class WorkFlowNodePluginFunctionsBase :ITransientDependency
    {
        public abstract string DisplayName { get; }
        public abstract string UniqeName { get; }


        /// <summary>
        /// 表单保存前( 做表单验证 或保存自定义数据)
        /// </summary>
        /// <returns></returns>
        public virtual Task BeforeSaveFormAsync(UpdateFormDataInput input, IWorkFlowManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }

        /// <summary>
        /// 表单保存后（保存自定义数据 或 其他操作）
        /// </summary>
        /// <returns></returns>
        public virtual Task AfterSaveFormAsync(UpdateFormDataInput input, IWorkFlowManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }

        /// <summary>
        /// 发送下一步前（主线）（数据验证）
        /// </summary>
        /// <returns></returns>
        public virtual Task BeforeSendToNextNodeAsync(IWorkFlowManager workFlowManager, Guid nodeId, List<long> userids_next, ActionScheme actionScheme_next, string replyMsg)
        {
            return AbpTaskCache.CompletedTask;
        }

        /// <summary>
        /// 发送下一步后 （主线）
        /// </summary>
        /// <returns></returns>
        public virtual Task AfterSendToNextNodeAsync(IWorkFlowManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }

        /// <summary>
        /// 是否显示退回按钮
        /// </summary>
        /// <param name="workFlowManager"></param>
        /// <returns></returns>

        public virtual Task<bool> CanReturnAsync(IWorkFlowManager workFlowManager)
        {
            return Task.FromResult(true);
        }


        /// <summary>
        /// 自定义退回方法
        /// </summary>
        /// <param name="workFlowManager"></param>
        /// <returns>是否已经退回（未实现方法返回false, 已退回则返回ture）</returns>
        public virtual Task<bool> DiyReturnMethodAsync(
            IWorkFlowManager workFlowManager, WorkFlowProcessDto current, Guid nodeId,
            string replyMsg)
        {
            return Task.FromResult(false);
        }

        /// <summary>
        /// 发送到下一步前，在弹窗选人前验证表单必填项(抛出友好异常)
        /// </summary>
        public virtual Task<StateWhenSubmit> CheckDataBeforeSelelctUsersToNextNode(IWorkFlowManager workFlowManager, bool isNeedToSelectUsers)
        {
            var a = new StateWhenSubmit
            {
                IsNeedToSelectUsers = isNeedToSelectUsers,
                IsRequired = true
            };
            return Task.FromResult(a);
        }

        /// <summary>
        /// 自定义下一步方法
        /// </summary>
        /// <param name="workFlowManager"></param>
        /// <returns>是否已经发送（未实现方法返回false, 已发送则返回ture）</returns>
        public virtual Task<bool> DiyGoNextAsync(
            IWorkFlowManager workFlowManager, Guid nodeId, List<long> userids_next, List<long> turnRoundUserList, ActionScheme actionScheme_next, string replyMsg)
        {
            return Task.FromResult(false);
        }
        /// <summary>
        /// 调整下一步节点的待选项，清空则当前节点为办结节点
        /// </summary>
        /// <param name="list"></param>
        /// <param name="workFlowManager"></param>
        /// <returns></returns>
        public virtual async Task<List<IWorkflowNodeDefinition>> CheckNextNodeListAsync(List<IWorkflowNodeDefinition> list, IWorkFlowManager workFlowManager)
        {
            await Task.FromResult(0);
            return list;
        }

        /// <summary>
        /// 调整待选人员和默认选定的人员
        /// </summary>
        /// <param name="result"></param>
        /// <param name="workFlowManager"></param>
        /// <returns></returns>
        public virtual async Task FilterUserListAsync(GetUserListResult result, IWorkFlowManager workFlowManager, string signal)
        {
            // 定制默认选中的下一步
            await Task.FromResult(0);
        }

        public virtual Task<FormDataOutput> AlterFormDataOutput(FormDataOutput output, IWorkFlowManager workFlowManager)
        {
            return Task.FromResult(output);
        }

        public virtual Task<string> GetDefaultMsgAsync(IWorkFlowManager workFlowManager)
        {
            return Task.FromResult("");
        }

        // 判断是否显示按钮
        public virtual Task<bool> ShowSecificBtn(IWorkFlowManager workFlowManager)
        {
            return Task.FromResult(true);
        }

        public virtual async Task<List<FormDataItemDescription>> FilterFormFieldsPermissionAsync(
            List<FormDataItemDescription> data
            , IWorkFlowManager workFlowManager) 
        {
            var current = await workFlowManager.GetCurrentProcessAsync();
            var actionState = await workFlowManager.CheckActionStateAsync();
            var isBranchLine = await workFlowManager.IsBranchLineAsync();
            
            if (actionState == ActionState.Todo && !isBranchLine && current.CanEditForm)
            {
                return data;
            }
            else
            {
                return new List<FormDataItemDescription>();
            }
        }

        protected static async Task<bool> GoNextAutoAsync(
            IWorkFlowManager workFlowManager, string replyMsg)
        {
            // 自动匹配人员，发送下一步
            var current = await workFlowManager.GetCurrentProcessAsync();
            var isHasOther = await workFlowManager.IsHasOtherOperatorAsync(current);
            if (!isHasOther)
            {
                var nextIdList = await workFlowManager.GetNextAsync();
                if (!nextIdList.IsNullOrEmpty())
                {
                    var nextNode = nextIdList[0];

                    //调取人员选择框的选项及默认选项
                    var userIds = await workFlowManager
                        .GetUserListAsync(nextNode.Definition.NodeId, null, nextNode.Definition.ToUserFilter());
                    var userIdList = userIds.DefaultSelectedUsers.Select(c => c.Id).ToList();
                    if (userIdList.Count > 0)
                    {
                        await workFlowManager.GoNext(current, userIdList, null, nextNode.Definition.NodeId, nextNode.Definition.ActionScheme, replyMsg);
                        return true;
                    }
                }
            }
            else
            {
                await workFlowManager.HandOverToNextInOrderAsync(current, replyMsg);
                return true;
            }

            return false;
        }

    }
}
